home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Collections: Topik
/
Topik - Disk 16 - KnowAboutIt (19xx)(Topik Public Domain)(PD)[WB].zip
/
Topik - Disk 16 - KnowAboutIt (19xx)(Topik Public Domain)(PD)[WB].adf
/
MicroRayDbw
/
output.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-12-11
|
8KB
|
276 lines
/************************************************************************
* *
* Copyright (c) 1988, David B. Wecker *
* All Rights Reserved *
* *
* This file is part of DBW_uRAY *
* *
* DBW_uRAY is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY. No author or distributor accepts *
* responsibility to anyone for the consequences of using it or for *
* whether it serves any particular purpose or works at all, unless *
* he says so in writing. Refer to the DBW_uRAY General Public *
* License for full details. *
* *
* Everyone is granted permission to copy, modify and redistribute *
* DBW_uRAY, but only under the conditions described in the *
* DBW_uRAY General Public License. A copy of this license is *
* supposed to have been given to you along with DBW_uRAY so you *
* can know your rights and responsibilities. It should be in a file *
* named COPYING. Among other things, the copyright notice and this *
* notice must be preserved on all copies. *
************************************************************************
* *
* Authors: *
* DBW - David B. Wecker *
* *
* Versions: *
* V1.0 881023 DBW - First released version *
* V1.1 881110 DBW - Fixed scan coherence code *
* V1.2 881125 DBW - Removed ALL scan coherence code (useless) *
* added "fat" extent boxes *
* *
************************************************************************/
#include "uray.h"
/************************************************************************/
/************ module to write output files ******************************/
/************************************************************************/
void wfil(fil,cnt,val) /* write a number to a file (68000 order) */
FILE *fil;
short cnt;
char val[];
{
#ifdef MCH_AMIGA
fwrite(val,cnt,1,fil);
#else
while (cnt--) fwrite(&val[cnt],1,1,fil);
#endif
}
short rfil(fil,cnt,val) /* read a number from a file (68000 order) */
FILE *fil;
short cnt;
char val[];
{
#ifdef MCH_AMIGA
if (fread(val,cnt,1,fil) != 1) return(-1);
#else
while (cnt--) if (fread(&val[cnt],1,1,fil) != 1) return(-1);
#endif
return(0);
}
/* create output files */
void coutputs() {
int i;
/* first create the output .tmp file */
if (bpp) {
sprintf(str,"%s.tmp",basnam);
fp = fopen(str,"w");
if (!fp) leave("Bad output file");
/* write out the header */
wfil(fp,sizeof(short),&startrow);
wfil(fp,sizeof(short),&endrow);
wfil(fp,sizeof(short),&cols);
wfil(fp,sizeof(short),&bpp);
}
/* second, create the output .ilbm file */
sprintf(str,"%s.ilbm",basnam);
fp2 = fopen(str,"w");
if (!fp2) leave("Bad output file (ilbm)");
/* write out the header */
sprintf(str,"FORM"); fwrite(str,1,4,fp2);
pos1 = ftell(fp2);
lng = FORMsize; wfil(fp2,sizeof(long),&lng);
sprintf(str,"ILBM"); fwrite(str,1,4,fp2);
sprintf(str,"BMHD"); fwrite(str,1,4,fp2);
lng = BMHDsize; wfil(fp2,4,&lng);
wrd = cols; wfil(fp2,2,&wrd); /* width */
wrd = rows; wfil(fp2,2,&wrd); /* height */
wrd = startrow; wfil(fp2,2,&wrd); /* top */
wrd = 0; wfil(fp2,2,&wrd); /* left */
byt = DEPTH; wfil(fp2,1,&byt); /* Depth */
byt = 0; wfil(fp2,1,&byt); /* mask */
byt = 1; wfil(fp2,1,&byt); /* compress */
byt = 0; wfil(fp2,1,&byt); /* pad */
wrd = 0; wfil(fp2,2,&wrd); /* transparency */
byt = 10; wfil(fp2,1,&byt); /* aspect x */
byt = 11; wfil(fp2,1,&byt); /* aspect y */
wrd = cols; wfil(fp2,2,&wrd); /* page width */
wrd = rows; wfil(fp2,2,&wrd); /* page height */
sprintf(str,"CAMG"); fwrite(str,1,4,fp2);
lng = CAMGsize; wfil(fp2,4,&lng);
lng = HAM | LACE; wfil(fp2,4,&lng);
sprintf(str,"CMAP"); fwrite(str,1,4,fp2);
lng = CMAPsize; wfil(fp2,4,&lng);
pos3 = ftell(fp2);
colors[0][0] = colors[0][1] = colors[0][2] = 0;
lstcolor = 1;
fwrite(colors,1,48,fp2);
fwrite(colors,1,48,fp2);
sprintf(str,"BODY"); fwrite(str,1,4,fp2);
pos2 = ftell(fp2);
lng = BODYsize; wfil(fp2,4,&lng);
lsize = 0L;
}
/* write a scan line to the output files */
void woutputs(sline)
short sline;
{
int i,j,k,c,d,old[3],new[3],x,pxl,scr,addok,
index,bdist,ndist,maxdist,dcol,dval;
unsigned char buf[512],planes[6][128],b1,b2;
/* print out 'dots' so the user knows we're working */
if (sline % 50 == 0 || sline == startrow)
printf("Row %4d: ",sline);
printf(".");
if (sline % 50 == 49) printf("\n");
else fflush(stdout);
/* write out a scan line to .tmp file */
if (bpp) {
wfil(fp,sizeof(short),&sline);
/* now write out each color of the scan line */
for (i=0; i<3; i++) {
/* write out 24 bits per pixel */
if (cols == obpsl) fwrite(outary[i],1,obpsl,fp);
/* or 12 bits per pixel (need to pack it) */
else {
for (x=0; x<cols; x++) {
b1 = outary[i][x];
b2 = b1 >> 4;
if (x & 1) buf[x>>1] |= b2 & 0x0F;
else buf[x>>1] = b1 & 0xF0;
}
fwrite(buf,1,obpsl,fp);
}
}
fflush(fp);
}
/* initialize the HAM encoding */
for (i=0; i<3; i++) old[i] = 0;
for (d=0; d<6; d++)
for (i=0; i<MAXBYTE; i++)
planes[d][i] = 0;
/* allow 1 new color to be added to colors[] per scan line (max) */
addok = 1;
/* set the amount of error for adding new colors[] */
if (sline < (rows>>1)) maxdist = 127;
else maxdist = 63;
for (x=0; x<cols; x++,dcol++) {
/* first get the desired old values (dither as necessary) */
for (i=0; i<3; i++) {
dval = ((int)outary[i][x]) & 0xF;
new[i] = ((int)outary[i][x]) & 0xF0;
if (dval && new[i] != 0xF0 && dval > (random() & 0xF))
new[i] += 0x10;
}
/* get the best absolute color */
bdist = 9999;
for (i=0; i<lstcolor; i++) {
ndist = 0;
for (j=0; j<3; j++)
ndist += ABS(new[j] - (int)colors[i][j]);
if (ndist < bdist) {
bdist = ndist;
index = i;
}
}
/* now find worst color (to make relative change) */
ndist = 0;
j = -1;
for (i = 0; i<3; i++) {
if ((k=ABS(new[i] - old[i])) > j) {
c = i;
j = k;
}
ndist += k;
}
/* subtract off the gun we want to fix */
ndist -= j;
/* if relative is best, flag it (index = -1) (unless first pixel) */
if (x > 0 && ndist < bdist) {
bdist = ndist;
index = -1;
}
/* decide if we need a new color in the color table */
if (addok && lstcolor < 16 && bdist > maxdist) {
for (i=0; i<3; i++) colors[lstcolor][i] = (unsigned char)new[i];
addok = 0;
bdist = 0;
index = lstcolor++;
# if DEBUG_ilbm
printf("Adding color %2d: %02x%02x%02x\n",index,
new[0],new[1],new[2]);
# endif
}
/* now change the gun (for relative) */
if (index == -1) {
pxl = (old[c] = new[c]) >> 4;
switch (c) {
case 0: pxl |= 0x20; break;
case 1: pxl |= 0x30; break;
case 2: pxl |= 0x10; break;
}
}
else {
pxl = index;
for (i=0; i<3; i++) old[i] = (int)colors[index][i];
}
# if DEBUG_ilbm
printf("%4d,%4d: %02x (%d)\n",sline,x,pxl,bdist);
# endif
/* and store the pixel away */
j = x >> 3;
k = 7 - (x & 0x7);
for (i=0; i<DEPTH; i++) {
planes[i][j] |= (pxl & 1) << k;
pxl >>= 1;
}
}
/* now pack the row away (RKM run length encoding) */
for (i=0; i < DEPTH; i++) {
wrd = PackRow(planes[i],buf,MAXBYTE);
lsize += (long)wrd;
fwrite(buf,1,wrd,fp2);
}
}